package com.njtcedu.microblog.intranet.user.repository;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.codec.digest.DigestUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import com.njtcedu.microblog.common.entity.User;
import com.njtcedu.microblog.common.entity.UserInfo;
import com.njtcedu.microblog.common.exception.BusinessException;
import com.njtcedu.microblog.common.repository.AbstractRepository;
import com.njtcedu.microblog.common.util.Convert;
import com.njtcedu.microblog.common.util.StringUtils;
import com.njtcedu.microblog.common.web.domain.PageModel;
import com.njtcedu.microblog.intranet.user.web.request.UserGenerateRequest;
import com.njtcedu.microblog.intranet.user.web.request.UserSearchRequest;
import com.njtcedu.microblog.intranet.user.web.response.UserInfoResponse;

@Repository
public class UserRepository extends AbstractRepository {

	public User get(Integer userId) {
		return hibernateAccess.get(User.class, userId);
	}

	public void createUser(UserGenerateRequest request) {
		if (!StringUtils.hasText(request.getAccount())) {
			throw new BusinessException("用户账户不能为空");
		}
		
		User user = hibernateAccess.findUniqueResult(DetachedCriteria.forClass(User.class).add(Restrictions.eq("account", request.getAccount())));
		if (user !=null) {
			throw new BusinessException("用户[" + request.getAccount() + "]已经存在");
		}
		
		user = new User();
		user.setAccount(request.getAccount());
		user.setPassword(DigestUtils.md5Hex(request.getPassword()));
		user.setUserType(request.getUserType());
		user.setStatus("Y");
		hibernateAccess.persist(user);
		hibernateAccess.currentSession().flush();
		
		UserInfo userInfo = new UserInfo();
		userInfo.setNickName(request.getNickName());
		userInfo.setUser(user);
		userInfo.setSignupDate(getSysDate());
		userInfo.setUserImage("/upload/image/noavatar.gif");
		hibernateAccess.persist(userInfo);
		hibernateAccess.currentSession().flush();
		
		user.setUserInfo(userInfo);
		hibernateAccess.update(user);
	}


	public boolean removeUser(Integer userId) {
		User user = hibernateAccess.get(User.class, userId);
		if (user == null || "N".equalsIgnoreCase(user.getStatus())) {
			throw new BusinessException("用户不存在");
		}
		user.setStatus("N");
		hibernateAccess.update(user);
		return true;
	}
	
	public PageModel<UserInfoResponse> userList(UserSearchRequest searchRequest, Integer pageNo, Integer pageSize) {
		if (searchRequest == null) {
			return null;
		}
		
		DetachedCriteria criteria = createRestrictionsCriteria(searchRequest);

		List<UserInfo> userInfos = hibernateAccess.find(criteria, (pageNo - 1) * pageSize, pageSize);
				
		List<UserInfoResponse> response = new ArrayList<UserInfoResponse>();
		for (UserInfo userInfo : userInfos) {
			response.add(UserInfoResponse.createUserInfo(userInfo));
		}

		Long totalRecords = totalRecords(searchRequest);
		return createPageModel(pageNo, pageSize, totalRecords, response);

	}

	private DetachedCriteria createRestrictionsCriteria(UserSearchRequest searchRequest) {
		DetachedCriteria criteria = DetachedCriteria.forClass(UserInfo.class);
		if (StringUtils.hasText(searchRequest.getNickName())) {
			criteria.add(Restrictions.like("nickName", searchRequest.getNickName(), MatchMode.ANYWHERE));
		}

		if (StringUtils.hasText(searchRequest.getSignupDateFrom())) {
			Date signupDateTo = StringUtils.hasText(searchRequest.getSignupDateTo()) ? Convert.toDate(searchRequest.getSignupDateTo(), "dd/mm/yyyy", getSysDate()) : getSysDate();
			criteria.add(Restrictions.between("signupDate", Convert.toDate(searchRequest.getSignupDateFrom(), "dd/mm/yyyy", getSysDate()), signupDateTo));
		}
		
		if (StringUtils.hasText(searchRequest.getSignupDateTo())) {
			criteria.add(Restrictions.le("signupDate", Convert.toDate(searchRequest.getSignupDateTo(), "dd/mm/yyyy", getSysDate())));
		}
		
		criteria = criteria.createCriteria("user").add(Restrictions.eq("status", "Y"));
		
		if (StringUtils.hasText(searchRequest.getAccount())) {
			criteria.add(Restrictions.like("account", searchRequest.getAccount(), MatchMode.ANYWHERE));
		}
		
		
		return criteria;
	}

	private Long totalRecords(UserSearchRequest searchRequest) {
		DetachedCriteria criteria = createRestrictionsCriteria(searchRequest);
		criteria.setProjection(Projections.rowCount());
		Long totalRecords = hibernateAccess.findUniqueResult(criteria);
		return totalRecords == null ? 0L : totalRecords;
	}
}
